Blueprint Help Send comments on this topic.
Basic GUI Modifications

Glossary Item Box

Back to Creating the Projects

Basic Modifications to GUI Code

Select files from the Solution Explorer file tree and make the following modifications

 


EnlargeClick to enlarge

Gui.cpp

Modify dialog creation in InitInstance() to

BOOL CGUIApp::InitInstance()
{
   ...

   CGUIDlg* dlg = new CGUIDlg();
   m_pMainWnd = dlg;
   dlg->Create( IDD_GUI_DIALOG );

   return TRUE;
}

GuiDlg.h

Modify the Dialog definition to include

class CGUIDlg : public CDialog
{
   ...
protected:
   ...

   LRESULT DefWindowProc( UINT message, WPARAM wParam, LPARAM );
   afx_msg void OnClose();

public:
   ~CGUIDlg();

   ...
};

GuiDlg.cpp

Modify the Dialog file to include

#include <projectheader.hpp>
#include <Process1Process_includes.
hpp>
#include <GUI/Win32/CPP/Include/Win32_Process.hpp>

Comment out or remove

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

Add Close to message map

BEGIN_MESSAGE_MAP(CGUIDlg, CDialog)
   ...
   ON_WM_CLOSE()
END_MESSAGE_MAP()

Add dialog registration and process startup to OnInitDialog()

BOOL CGUIDlg::OnInitDialog()
{
   ...

   // TODO: Add extra initialization here
   ::CLIP::SetCallbackWindow( this->GetSafeHwnd(), this );

   Process1Process* process = new Process1Process();
   process->Startup();

   return TRUE;
}

Add overrides for dialog functions

LRESULT CGUIDlg::DefWindowProc( UINT message, WPARAM wParam, LPARAM lParam )
{
   CLIP::ProcessPumpMessage( message, wParam, lParam );
   return CDialog::DefWindowProc( message, wParam, lParam );
}

void CGUIDlg::OnClose()
{
   ClpExit(0);
   CDialog::OnClose();
}

CGUIDlg::~CGUIDlg()
{
   // we will add things here later
}

GUI Dialogs

You can either create your own dialogs

The Start Button will be used to start the application running. Whilst the X will be used to exit the application.

or copy the files GUI.rc, resource.h, OutputDialog.h and OutputDialog.cpp into the project (you will probably need to exit VisualStudio and delete the GUI.APS file).

The Output dialog is used for display of the data and includes a ViewerPixmap (CPixmap.h, CPixmap.cpp, CViewerPixmap.h, CViewerPixmap.cpp) for the display, counters for calculating frame rates and a couple of functions for Initializing and setting the pixmap.

NB. Both dialogs include frame rate counters (processing frames and displayed frames which are reduced by REDUCTION:1 as we wish to see how the processing performs without being constrained by the graphics). This frame counter code could be emitted without loss of functionality and is shown in magenta.

OutputDialog.h

#include "CViewerPixmap.h"

class COutputDialog : publicCDialog
{
...

public:
   // access to pixmap
   unsigned char* GetPixelData();
   void           UpdatePixelData();
   unsigned int   GetPixmapSize();

protected:
   ...
   virtual BOOL OnInitDialog();
   afx_msg void OnPaint();
   afx_msg void OnClose();

private:
   // create pixmap 
   void Initialise();

private:
   CViewerPixmap* mViewerPixmap;

   // frame counters
   LARGE_INTEGER  mFrequency;
   LARGE_INTEGER  mPreviousCount;
   float          mClockPeriodMicroSec;
   bool           mFirstTime;
};

OutputDialog.cpp

#include <ProjectHeader.hpp>
...

COutputDialog::COutputDialog( CWnd* pParent )
 : CDialog( COutputDialog::IDD, pParent )
{
   // initialise the frame rate counters
   mFirstTime = true;
   QueryPerformanceFrequency( &mFrequency );
   mClockPeriodMicroSec = 1000000.0f / (float) mFrequency.QuadPart;
}

COutputDialog::~COutputDialog()
{
   // delete the pixmap
   delete mViewerPixmap;
}

BEGIN_MESSAGE_MAP(COutputDlg, CDialog)
   ON_WM_CLOSE()
   ON_WM_PAINT()
END_MESSAGE_MAP()

BOOL COutputDialog::OnInitDialog()
{
   CDialog::OnInitDialog();
   Initialise();

   return TRUE;
}

void COutputDlg::OnClose()
{
   ClpExit(0);
   CDialog::OnClose();
}

void COutputDialog::OnPaint()
{

   // update the frame rate counters
   if ( !mFirstTime )
   {
      LARGE_INTEGER CurrentCount;
      QueryPerformanceCounter( &CurrentCount );
   
      float TimeTakenMicroSec = ( CurrentCount.QuadPart - mPreviousCount.QuadPart ) * mClockPeriodMicroSec;
     
      mPreviousCount = CurrentCount;
             
      float AverageFrameRate = 1.0f / ( TimeTakenMicroSec * 0.000001f );
      CString Text;
      Text.Format( " FPS = %.1f", AverageFrameRate );
      SetWindowText( Text );
   }
   else
   {
      mFirstTime = false;
      QueryPerformanceCounter(&mPreviousCount);
   }

   // update the pixmap
   mViewerPixmap->Update();  

   CDialog::OnPaint();
}  

void COutputDialog::Initialise()
{
   // Create the pixmap
   mViewerPixmap = new CViewerPixmap( this->GetDC()->GetSafeHdc(), GRID_SIZE, GRID_SIZE );
}

unsigned char* COutputDialog::GetPixelData()
{
    return mViewerPixmap->GetBitmapData();
}

void COutputDialog::UpdatePixelData()
{
    mViewerPixmap->CommitBitmapData();
}

unsigned int COutputDialog::GetPixmapSize()
{
   return 0; // we will populate this later
}

The main GUI now needs to be updated to: interface to the Output dialog; add its own frame rate counters and provide callbacks for the Start Button

GuiDlg.h

#include "OutputDialog.h"

class CGUIDlg : public CDialog
{
...
public:
   CButton StartBtn;

protected:
    // start button callback
    afx_msg void OnBnClickedButton1();


public:
   // initialise frame counters
   void Initialise();

   // Output interface
   void UpdatePixels( char* Pixmap, unsigned int FrameCount );

private:
   COutputDialog* mOutputDlg;

   // frame counters
   LARGE_INTEGER mFrequency;
   LARGE_INTEGER mPreviousCount;
   float mClockPeriodMicroSec;
   float mTotalTimeTakenMicroSec;
   unsigned int mPreviousFrameCount;
   unsigned int mTotalFrameCount;
   unsigned int mTimeSampleCount;
   bool mFirstTime;
};

GuiDlg.cpp

...

void CGUIDlg::DoDataExchange(CDataExchange* pDX)
{
   CDialog::DoDataExchange(pDX);
   DDX_Control(pDX, IDC_BUTTON1, StartBtn);
}

BEGIN_MESSAGE_MAP(CGUIDlg, CDialog)
...
   ON_BN_CLICKED(IDC_BUTTON1, &CGUIDlg::OnBnClickedButton1)
END_MESSAGE_MAP()

BOOL CGUIDlg::OnInitDialog()
{
   ...
   Initialise();

   // TODO: Add extra initialization here
   ...
}

...


void CGUIDlg::Initialise()
{
   CRect Rect;

   // position this dialog
   this->SetWindowPos( NULL, 0,0,0,0, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW );
   this->GetClientRect( &Rect );
   this->ClientToScreen( &Rect );

   // create output dialog
   mOutputDlg = new COutputDialog( this );
   mOutputDlg->Create( IDD_OUTPUT_DIALOG, this );
  
   // position/size output dialog
   mOutputDlg->SetWindowPos( NULL, Rect.right + 5, 0, GRID_SIZE + 6, GRID_SIZE + 32, SWP_NOZORDER | SWP_SHOWWINDOW );

   // initialise frame counters
   mFirstTime = true;
   QueryPerformanceFrequency(&mFrequency);
   mClockPeriodMicroSec = 1000000.0f / (float)mFrequency.QuadPart;
}

void CGUIDlg::OnBnClickedButton1()
{
   // start pressed - tell CLIP to start
   // TDB in Final GUI Modifications
}

void CGUIDlg::UpdatePixels( char* Pixmap, unsigned int FrameCount )
{
  
// update frame counters
   if ( !mFirstTime )
   {
      LARGE_INTEGER CurrentCount;
      QueryPerformanceCounter(&CurrentCount);
      mTotalTimeTakenMicroSec += ( CurrentCount.QuadPart - mPreviousCount.QuadPart ) * mClockPeriodMicroSec;
      mPreviousCount = CurrentCount;
      ++mTimeSampleCount;
      mTotalFrameCount += ( FrameCount - mPreviousFrameCount );
      mPreviousFrameCount = FrameCount;

      float AverageFrameRate = (float)mTotalFrameCount / ( mTotalTimeTakenMicroSec * 0.000001f );
      CString Text;
      Text.Format( " FPS = %.1f", AverageFrameRate );
      SetWindowText( Text );

      if ( mTimeSampleCount == TIME_SAMPLE_COUNT )
      {
         mTotalTimeTakenMicroSec = 0.0f;
         mTimeSampleCount = 0;
         mTotalFrameCount = 0;
      }
   }
   else
   {
      mFirstTime = false;
      QueryPerformanceCounter(&mPreviousCount);
      mPreviousFrameCount = FrameCount;
      mTotalTimeTakenMicroSec = 0.0f;
      mTimeSampleCount = 0;
      mTotalFrameCount = 0;
   }

   // draw pixels and refresh the display

   memcpy( mOutputDlg->GetPixelData(), Pixmap, mOutputDlg->GetPixmapSize() );

   mOutputDlg->UpdatePixelData();
   mOutputDlg->PostMessage( WM_PAINT );
}

The constant value 'GRID_SIZE' can be defined in the project header file by opening the file from the Solution Explorer Window and adding the following code

FDTD/Header Files/ProjectHeader.hpp

...

// TODO: Reference any additional headers or defines you need

#define GRID_SIZE   1024

#endif

The actual grid size could be modified for a finer/larger grid. However, many calculations later in the code will assume it is a power of 2.

Creating the Circuitry